package com.gp8.tier3;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
import java.util.Map.Entry;
import java.util.Random;

//Il faut faire des return pour renvoyer les objets au tier2, les syso ne servent qu'au log serveur (tier3)

public class ServiceGestionPiaffeurImpl implements ServiceGestionPiaffeur, Runnable, Serializable {

	private static final long serialVersionUID = 1L;
	private ArrayList<Piaffeur> listPiaffeursA = new ArrayList<Piaffeur>(); //Piaffeur abonnés
	private ArrayList<Piaffeur> listPiaffeursC = new ArrayList<Piaffeur>(); //Piaffeur connectés
	private HashMap<Piaffeur, ArrayList<Piaffeur>> listPiaffeursAbonnement = new HashMap<Piaffeur, ArrayList<Piaffeur>>(); //Liste des abonnements par Piaffeur
	private HashMap<Piaffeur, ArrayList<Piafferie>> listPiaffeursMessage = new HashMap<Piaffeur, ArrayList<Piafferie>>(); //Liste des messages par Piaffeur
	
	@Override
	public Piaffeur CreationCompte(String pMail, String pPseudo, String pPassword) throws RemoteException {
		Piaffeur piaffeur = new Piaffeur(pMail, pPseudo, pPassword);
		if (!listPiaffeursA.contains(piaffeur)) {
			listPiaffeursA.add(piaffeur);
			System.out.println("Compte créé avec mail = '" + pMail + "', pseudo = '" + pPseudo + "' et mdp = '" + pPassword + "'");
			return piaffeur;
		} else {
			System.out.println("Compte existant avec mail = '" + pMail + "', pseudo = '" + pPseudo + "' et mdp = '" + pPassword + "'");
			return null;
		}
	}

	@Override
	public Piaffeur ConnexionCompte(String pMail, String pPassword) throws RemoteException {
		int i = 0;
		while (i < listPiaffeursA.size()) {
			if (listPiaffeursA.get(i).getMail().equals(pMail) && listPiaffeursA.get(i).getPassword().equals(pPassword)) {
				break;
			}
			i++;
		}
		if (i < listPiaffeursA.size()) {
			Piaffeur piaffeur = listPiaffeursA.get(i);
			if (!listPiaffeursC.contains(piaffeur)) {
				listPiaffeursC.add(piaffeur);
			}
			System.out.println("Connexion de " + piaffeur.getPseudo());
			return piaffeur;
		} else {
			System.out.println("Tentative de connexion avec mail = '" + pMail + "' et mdp = '" + pPassword + "'");
			return null;
		}		
	}

	@Override
	public void DeconnexionCompte(Piaffeur pPiaffeur) throws RemoteException {

		if (listPiaffeursC.contains(pPiaffeur)) {
			listPiaffeursC.remove(pPiaffeur);
			System.out.println("Deconnexion de " + pPiaffeur.getPseudo());
		}

	}
	
	@Override
	public void SuppressionCompte(Piaffeur pPiaffeur) throws RemoteException {

		//On vérifie que la personne est connecté avant de supprimer son compte
		if (listPiaffeursC.contains(pPiaffeur)) {
			if (listPiaffeursA.contains(pPiaffeur)) {
				listPiaffeursA.remove(pPiaffeur);
				if (listPiaffeursAbonnement.containsKey(pPiaffeur)) {
					listPiaffeursAbonnement.remove(pPiaffeur);
				}
				if (listPiaffeursMessage.containsKey(pPiaffeur)) {
					listPiaffeursMessage.remove(pPiaffeur);
				}				
				System.out.println("Suppression de " + pPiaffeur.getPseudo());
			}
			listPiaffeursC.remove(pPiaffeur);
			System.out.println("Deconnexion de " + pPiaffeur.getPseudo());
		}
		
	}
	
	@Override
	public void AjouterAbonnement(Piaffeur suiveur, Piaffeur suivi) throws RemoteException {

		//On vérifie que la personne est connecté avant d'ajouter un abonnement
		if (listPiaffeursC.contains(suiveur)) {
			//On verifie l'existance de la personne à suivre
			if (listPiaffeursA.contains(suivi)) {
				ArrayList<Piaffeur> liste = listPiaffeursAbonnement.get(suiveur);
				if(liste == null) {
					liste = new ArrayList<Piaffeur>();
					liste.add(suivi);
					listPiaffeursAbonnement.put(suiveur, liste);
			    } else if (!liste.contains(suivi)) {
			    	listPiaffeursAbonnement.get(suiveur).add(suivi);
			    }
				System.out.println(suiveur.getPseudo() + " suit " + suivi.getPseudo());
			}
		}
	}
	
	@Override
	public void SupprimerAbonnement(Piaffeur suiveur, Piaffeur suivi) throws RemoteException {

		//On vérifie que la personne est connecté avant de supprimer un abonnement
		if (listPiaffeursC.contains(suiveur)) {
			ArrayList<Piaffeur> liste = listPiaffeursAbonnement.get(suiveur);
			if(liste != null && liste.contains(suivi)) {
				listPiaffeursAbonnement.get(suiveur).remove(suivi);
				System.out.println(suiveur.getPseudo() + " ne suit plus " + suivi.getPseudo());
			}
		}
	}
	
	@Override
	public ArrayList<Piaffeur> mesAbonnements(Piaffeur suiveur) throws RemoteException {

		//On vérifie que la personne est connecté avant de chercher les abonnement
		if (listPiaffeursC.contains(suiveur)) {
			System.out.println("Résultat abonnement " + listPiaffeursAbonnement.get(suiveur));
			return listPiaffeursAbonnement.get(suiveur);
		} else {
			System.out.println("Aucun abonnement : " + suiveur.getPseudo());
			return null;
		}
	}
	
	@Override
	public ArrayList<Piaffeur> mesAbonnes(Piaffeur suiveur) throws RemoteException {
		ArrayList<Piaffeur> listPiaffeursAbonnes = new ArrayList<Piaffeur>(); //Liste de mes abonnes
		
		//On vérifie que la personne est connecté avant de chercher les abonnes
		if (listPiaffeursC.contains(suiveur)) {

			for (Entry<Piaffeur, ArrayList<Piaffeur>> piaffeurAbonnement : listPiaffeursAbonnement.entrySet()) {
				Piaffeur piaffeur = piaffeurAbonnement.getKey();
				ArrayList<Piaffeur> listeAbonnement = piaffeurAbonnement.getValue();
				
				if (listeAbonnement.contains(suiveur)) {
					listPiaffeursAbonnes.add(piaffeur);
				}
			}
			if (!listPiaffeursAbonnes.isEmpty()) {
				System.out.println("Résultat abonnes " + listPiaffeursAbonnes);
				return listPiaffeursAbonnes;
			} else {
				System.out.println("Aucun abonne : " + suiveur.getPseudo());
				return null;
			}
		}
		return null;
	}
	
	@Override
	public void AjouterMessage(Piaffeur piaffeur, String message) throws RemoteException {
		
		//On vérifie que la personne est connecté avant d'ajouter un message
		if (listPiaffeursC.contains(piaffeur)) {
			ArrayList<Piafferie> liste = listPiaffeursMessage.get(piaffeur);
			Piafferie piafferie = new Piafferie(piaffeur, message);
			if(liste == null) {
				liste = new ArrayList<Piafferie>();
				liste.add(piafferie);
				listPiaffeursMessage.put(piaffeur, liste);
		    } else if (!liste.contains(piafferie)) {
		    	listPiaffeursMessage.get(piaffeur).add(piafferie);
		    }
			System.out.println("Message de " + piaffeur.getPseudo() + " ajouté");
		}
	}
	
	@Override
	public void SupprimerMessage(Piaffeur piaffeur, int numero) throws RemoteException {
		
		//On vérifie que la personne est connecté avant de supprimer un message
		if (listPiaffeursC.contains(piaffeur)) {
			ArrayList<Piafferie> liste = listPiaffeursMessage.get(piaffeur);
			if(liste != null && liste.size() > numero) {
				listPiaffeursMessage.get(piaffeur).remove(numero);
				System.out.println("Message de " + piaffeur.getPseudo() + " supprimé");
			}
		}
	}
	
	@Override
	public ArrayList<Piaffeur> RecherchePiaffeur(String pseudo) throws RemoteException {
		ArrayList<Piaffeur> listPiaffeursR = new ArrayList<Piaffeur>(); //Résultat de la recherche

		for (Piaffeur piaffeur : listPiaffeursA) {
			if (piaffeur.getPseudo().matches(".*"+pseudo+".*")) {
				listPiaffeursR.add(piaffeur);
			}
		}
		if (!listPiaffeursR.isEmpty()) {
			System.out.println("Résultat " + listPiaffeursR);
			return listPiaffeursR;
		} else {
			System.out.println("Aucun résultat pour : " + pseudo);
			return null;
		}
	}
	
	@Override
	public ArrayList<Piafferie> RechercheMessage(String message) throws RemoteException {
		ArrayList<Piafferie> listPiafferie = new ArrayList<Piafferie>(); //Résultat de la recherche

		for (Entry<Piaffeur, ArrayList<Piafferie>> listeMessage : listPiaffeursMessage.entrySet()) {
			Piaffeur piaffeur = listeMessage.getKey();
			ArrayList<Piafferie> listePiafferie = listeMessage.getValue();
			
			for (Piafferie piafferie : listePiafferie) {
				if (piafferie.getMessage().matches(".*"+message+".*")) {
					listPiafferie.add(piafferie);
				}
			}
		}
		if (!listPiafferie.isEmpty()) {
			System.out.println("Résultat " + listPiafferie);
			return listPiafferie;
		} else {
			System.out.println("Aucun résultat pour : " + message);
			return null;
		}
	}
	
	@Override
	public synchronized void run() {
		boolean live = true;
		while(live) {
//			try {
//				//mise en attente du thread entre 3 et 10 secondes
//				Long lWaitValue = new Double(new Random().nextInt(8)+3).longValue();
//				Thread.sleep(lWaitValue*1000);
//			} catch (InterruptedException e) {
//				System.out.println("erreur");
//			}
			
			Scanner scanInput;
			String choix = "N";
			System.out.println("Voulez-vous quitter ?");
			scanInput = new Scanner(System.in);
			choix = scanInput.nextLine();
			
			if (choix.equals("O")) {
				ServiceTroisiemeTier.Save();
				live = false;
			}
			
//			for (Piaffeur p : listPiaffeurs) {
//				try {
//					System.out.println(" === LISTE DES PIAFFERIES DE VOS FOLLOWS ===");
//					for (Piaffeur follow : p.getListPiaffeur()) {
//						for (Piafferie piafferie : follow.getListPiafferies()) {
//							System.out.println(" ========================================================");
//							System.out.println(" | auteur : "+piafferie.getAuteur()+"                    |");
//							System.out.println(" | date : "+piafferie.getDate()+"                    	 |");
//							System.out.println(" | message : "+piafferie.getMessage()+"                  |");
//							System.out.println(" ========================================================");
//						}
//					}
//						
//				} catch (RemoteException e) {
//					e.printStackTrace();
//					try {
//						this.DeconnexionCompte(p);
//					} catch (RemoteException e1) {
//						e1.printStackTrace();
//					}
//				}
//			}
		}
	}

}
